package com.feib.soeasy.model;

import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;


/**
 * @title (#)Payment.java<br>
 * @description 繳費單<br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/11/7 create by Jimmy Liu<br>
 */
@Entity
@Table(name = "PAYMENT")
public class Payment extends AuditEntity {

    private static final long serialVersionUID = -7189064155495481040L;

    /**
     * 帳單狀態代碼類別
     */
    public static final String PAYMENT_STATUS_CODE_KIND = "PAYMENT_STATUS";

    /**
     * 帳單狀態-待放行
     */
    public static final Integer PAYMENT_STATUS_WAIT_CONFIRM = new Integer(1);

    /**
     * 帳單狀態-待繳款
     */
    public static final Integer PAYMENT_STATUS_IN_PAYING = new Integer(2);

    /**
     * 帳單狀態-註銷中(不能銷帳)
     */
    public static final Integer PAYMENT_STATUS_IN_CANCELING = new Integer(3);

    /**
     * 帳單狀態-已註銷(不能銷帳)
     */
    public static final Integer PAYMENT_STATUS_CANCELED = new Integer(4);

    /**
     * 帳單狀態-已繳款
     */
    public static final Integer PAYMENT_STATUS_CLOSED = new Integer(5);

    /**
     * PK in Table
     */
    private Long paymentPk;

    /**
     * 所屬繳費匯入檔
     */
    private UploadFile uploadFile;

    /**
     * 所屬帳單業者</br>
     * 要等於 UPLOADFILE.GROUP</br>
     */
    private Group group;

    /**
     * 虛擬帳號-FEIB
     */
    private String virtualAccount;

    /**
     * 帳單狀態<br>
     * 1: 待放行<br>
     * 2: 待繳款<br>
     * 3: 註銷中(不能銷帳)<br>
     * 4: 已註銷(不能銷帳)<br>
     * 5: 已繳款<br>
     */
    private Integer paymentStatus;

    /**
     * 條碼-超商-第1段
     */
    private String barcodeStores1;

    /**
     * 條碼-超商-第2段
     */
    private String barcodeStores2;

    /**
     * 條碼-超商-第3段
     */
    private String barcodeStores3;

    /**
     * 條碼-超商-第1段(可貸)<br>
     * 可貸學費
     */
    private String barcodeStores1Loanable;

    /**
     * 條碼-超商-第2段(可貸)<br>
     * 可貸學費
     */
    private String barcodeStores2Loanable;

    /**
     * 條碼-超商-第3段(可貸)<br>
     * 可貸學費
     */
    private String barcodeStores3Loanable;

    /**
     * 條碼-郵局
     */
    private String barcodePost;

    /**
     * 繳費總金額<br>
     * 不可貸學費
     */
    private Long totalAmount;

    /**
     * 繳費總金額(可貸)<br>
     * 可貸學費
     */
    private Long totalLoanableAmount;

    /**
     * 繳費期間-迄
     */
    private Date payDue;

    /**
     * 帳單名稱<br>
     * ex:實習費帳單
     */
    private String paymentName;
    
    /**
     * 期別</br>
     * ex:2月份
     */
    private String period;
    
    /**
     * 繳款人Email
     */
    private String payerEmail;

    /**
     * 繳款人身分證號碼/統一編號
     */
    private String payerId;

    /**
     * 繳款人姓名
     */
    private String payerName;

    /**
     * 繳款人生日，西元年月日
     */
    private String payerBirthday;

    /**
     * Phone number
     */
    private String payerTelNo;

    /**
     * Mobile number
     */
    private String payerCellNo;

    /**
     * 繳款人住址
     */
    private String payerAddress;

    /**
     * 學號
     */
    private String studentId;

    /**
     * 學年度
     */
    private String academicYear;

    /**
     * 學期
     */
    private String semester;

    /**
     * 科系所
     */
    private String department;

    /**
     * 年級
     */
    private String grade;

    /**
     * 班級/班別
     */
    private String classNo;

    /**
     * 座號
     */
    private String seatNo;

    /**
     * 繳費明細
     */
    private List<PaymentItem> paymentItems;

    /**
     * 註銷紀錄<br>
     * 註銷放行後，此欄位才會有值，同時更新繳費狀態為已銷中<br>
     * 若只是經辦註銷，則新增一筆註銷紀錄到註銷資料表中，同時更新繳費狀態為註銷中</br>
     */
    private PaymentCanceled paymentCanceled;

    /**
     * 銷帳資料
     * 銷帳後，此欄位才會有值，同時更新繳費狀態為已繳款<br>
     */
    private WriteOffPayment writeOffPayment;
    
    /**
     * 擴充欄位
     */
    private ExtraColumns extraColumns;
    
    /**
     * 繳費單 PDF 檔存放路徑(完整路徑)
     */
    private String pdfFilePathOnServer;
    
    /**
     * 繳費單PDF檔檔名
     */
    private String pdfFileName;
    
    /**
     * 注意事項
     */
    private String paymentNote1;
    
    /**
     * 最新消息
     */
    private String paymentNote2;
    
    /**
     * 備註
     */
    private String paymentNote3;
    
    /**
     * 主辦銀行<br />
     * ex:遠東銀行台北忠孝分行 (805-0311)
     */
    private String mainBank;
    
    /**
     * 銷帳後實繳金額<br> 
     */
    private Long realPayAmount;
    //private Long real_pay_amount;
    

    /**
     * @return the paymentPk
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="PAYMENT_PK", nullable=false)
    public Long getPaymentPk() {
        return paymentPk;
    }


    /**
     * @param paymentPk the paymentPk to set
     */
    public void setPaymentPk(Long paymentPk) {
        this.paymentPk = paymentPk;
    }


    /**
     * @return the uploadFile
     */
    @ManyToOne
    @JoinColumn(name="UPLOAD_FILE_PK", nullable=false)
    public UploadFile getUploadFile() {
        return uploadFile;
    }


    /**
     * @param uploadFile the uploadFile to set
     */
    public void setUploadFile(UploadFile uploadFile) {
        this.uploadFile = uploadFile;
    }


    /**
     * @return the group
     */
    @ManyToOne
    @JoinColumn(name="GROUP_PK", nullable=false)
    public Group getGroup() {
        return group;
    }


    /**
     * @param group the group to set
     */
    public void setGroup(Group group) {
        this.group = group;
    }


    /**
     * @return the virtualAccount
     */
    @Column(name="VIRTUAL_ACCOUNT", nullable=false, length=20)
    public String getVirtualAccount() {
        return virtualAccount;
    }



    /**
     * @param virtualAccount the virtualAccount to set
     */
    public void setVirtualAccount(String virtualAccount) {
        this.virtualAccount = virtualAccount;
    }



    /**
     * @return the paymentStatus
     */
    @Column(name="PAYMENT_STATUS", nullable=false)
    public Integer getPaymentStatus() {
        return paymentStatus;
    }



    /**
     * @param paymentStatus the paymentStatus to set
     */
    public void setPaymentStatus(Integer paymentStatus) {
        this.paymentStatus = paymentStatus;
    }


    /**
     * @return the barcodeStores1
     */
    @Column(name="BARCODE_STORES_1", length=9)
    public String getBarcodeStores1() {
        return barcodeStores1;
    }



    /**
     * @param barcodeStores1 the barcodeStores1 to set
     */
    public void setBarcodeStores1(String barcodeStores1) {
        this.barcodeStores1 = barcodeStores1;
    }


    /**
     * @return the barcodeStores2
     */
    @Column(name="BARCODE_STORES_2", length=20)
    public String getBarcodeStores2() {
        return barcodeStores2;
    }



    /**
     * @param barcodeStores2 the barcodeStores2 to set
     */
    public void setBarcodeStores2(String barcodeStores2) {
        this.barcodeStores2 = barcodeStores2;
    }

 
    /**
     * @return the barcodeStores3
     */
    @Column(name="BARCODE_STORES_3", length=15)  
    public String getBarcodeStores3() {
        return barcodeStores3;
    }



    /**
     * @param barcodeStores1 the barcodeStores1 to set
     */
    public void setBarcodeStores3(String barcodeStores3) {
        this.barcodeStores3 = barcodeStores3;
    }


    
    
    /**
     * @return the barcodeStores1Loanable
     */
    @Column(name="BARCODE_STORES_1_LOAN", length=9) 
    public String getBarcodeStores1Loanable() {
        return barcodeStores1Loanable;
    }


    
    /**
     * @param barcodeStores1Loanable the barcodeStores1Loanable to set
     */
    public void setBarcodeStores1Loanable(String barcodeStores1Loanable) {
        this.barcodeStores1Loanable = barcodeStores1Loanable;
    }


    
    /**
     * @return the barcodeStores2Loanable
     */
    @Column(name="BARCODE_STORES_2_LOAN", length=20) 
    public String getBarcodeStores2Loanable() {
        return barcodeStores2Loanable;
    }


    
    /**
     * @param barcodeStores2Loanable the barcodeStores2Loanable to set
     */
    public void setBarcodeStores2Loanable(String barcodeStores2Loanable) {
        this.barcodeStores2Loanable = barcodeStores2Loanable;
    }


    /**
     * @return the barcodeStores3Loanable
     */
    @Column(name="BARCODE_STORES_3_LOAN", length=15)  
    public String getBarcodeStores3Loanable() {
        return barcodeStores3Loanable;
    }


    
    /**
     * @param barcodeStores3Loanable the barcodeStores3Loanable to set
     */
    public void setBarcodeStores3Loanable(String barcodeStores3Loanable) {
        this.barcodeStores3Loanable = barcodeStores3Loanable;
    }


    /**
     * @return the barcodePost
     */
    @Column(name="BARCODE_POST", length=30)
    public String getBarcodePost() {
        return barcodePost;
    }



    /**
     * @param barcodePost the barcodePost to set
     */
    public void setBarcodePost(String barcodePost) {
        this.barcodePost = barcodePost;
    }


    /**
     * @return the totalAmount
     */
    @Column(name="TOTAL_AMOUNT")
    public Long getTotalAmount() {
        return totalAmount;
    }


    /**
     * @param totalAmount the totalAmount to set
     */
    public void setTotalAmount(Long totalAmount) {
        this.totalAmount = totalAmount;
    }



    /**
     * @return the totalLoanableAmount
     */
    @Column(name="TOTAL_LOANABLE_AMOUNT")
    public Long getTotalLoanableAmount() {
        return totalLoanableAmount;
    }



    /**
     * @param totalLoanableAmount the totalLoanableAmount to set
     */
    public void setTotalLoanableAmount(Long totalLoanableAmount) {
        this.totalLoanableAmount = totalLoanableAmount;
    }


    /**
     * @return the paymentName
     */
    @Column(name="PAYMENT_NAME", length=50)
    public String getPaymentName() {
        return paymentName;
    }



    /**
     * @param paymentName the paymentName to set
     */
    public void setPaymentName(String paymentName) {
        this.paymentName = paymentName;
    }

    
    
    /**
     * @return the period
     */
    @Column(name="PERIOD", length=50)
    public String getPeriod() {
        return period;
    }


    
    /**
     * @param period the period to set
     */
    public void setPeriod(String period) {
        this.period = period;
    }


    /**
     * @return the payerEmail
     */
    @Column(name="PAYER_EMAIL", length=100)
    public String getPayerEmail() {
        return payerEmail;
    }


    
    /**
     * @param payerEmail the payerEmail to set
     */
    public void setPayerEmail(String payerEmail) {
        this.payerEmail = payerEmail;
    }
    

    /**
     * @return the payerId
     */
    @Column(name="PAYER_ID", length=10)
    public String getPayerId() {
        return payerId;
    }


    /**
     * @param payerId the payerId to set
     */
    public void setPayerId(String payerId) {
        this.payerId = payerId;
    }


    /**
     * @return the payerName
     */
    @Column(name="PAYER_NAME", length=68)
    public String getPayerName() {
        return payerName;
    }


    /**
     * @param payerName the payerName to set
     */
    public void setPayerName(String payerName) {
        this.payerName = payerName;
    }


    /**
     * @return the payerBirday
     */
    @Column(name="PAYER_BIRTHDAY", length=8)
    public String getPayerBirthday() {
        return payerBirthday;
    }


    /**
     * @param payerBirday the payerBirday to set
     */
    public void setPayerBirthday(String payerBirthday) {
        this.payerBirthday = payerBirthday;
    }
    
    /**
     * @return 傳回 payerTelNo。
     */
    @Column(name = "PAYER_TELNO", length = 20)
    public String getPayerTelNo() {
        return payerTelNo;
    }

    /**
     * @param payerTelNo 要設定的 payerTelNo。
     */
    public void setPayerTelNo(String payerTelNo) {
        this.payerTelNo = payerTelNo;
    }

    /**
     * @return 傳回 payerCellNo。
     */
    @Column(name = "PAYER_CELLNO", length = 20)
    public String getPayerCellNo() {
        return payerCellNo;
    }

    /**
     * @param payerCellNo 要設定的 payerCellNo。
     */
    public void setPayerCellNo(String payerCellNo) {
        this.payerCellNo = payerCellNo;
    }


    /**
     * @return the payerAddress
     */
    @Column(name="PAYER_ADDRESS", length=255)
    public String getPayerAddress() {
        return payerAddress;
    }



    /**
     * @param payerAddress the payerAddress to set
     */
    public void setPayerAddress(String payerAddress) {
        this.payerAddress = payerAddress;
    }



    /**
     * @return the studentId
     */
    @Column(name="STUDENT_ID", length=20)
    public String getStudentId() {
        return studentId;
    }



    /**
     * @param studentId the studentId to set
     */
    public void setStudentId(String studentId) {
        this.studentId = studentId;
    }




    /**
     * @return the academicYear
     */
    @Column(name="ACADEMIC_YEAR", length=10)
    public String getAcademicYear() {
        return academicYear;
    }



    /**
     * @param academicYear the academicYear to set
     */
    public void setAcademicYear(String academicYear) {
        this.academicYear = academicYear;
    }



    /**
     * @return the semester
     */
    @Column(name="SEMESTER", length=10)
    public String getSemester() {
        return semester;
    }



    /**
     * @param semester the semester to set
     */
    public void setSemester(String semester) {
        this.semester = semester;
    }



    /**
     * @return the department
     */
    @Column(name="DEPARTMENT", length=40)
    public String getDepartment() {
        return department;
    }



    /**
     * @param department the department to set
     */
    public void setDepartment(String department) {
        this.department = department;
    }



    /**
     * @return the grade
     */
    @Column(name="GRADE", length=10)
    public String getGrade() {
        return grade;
    }



    /**
     * @param grade the grade to set
     */
    public void setGrade(String grade) {
        this.grade = grade;
    }


    /**
     * @return the classNo
     */
    @Column(name="CLASS_NO", length=10)
    public String getClassNo() {
        return classNo;
    }



    /**
     * @param classNo the classNo to set
     */
    public void setClassNo(String classNo) {
        this.classNo = classNo;
    }



    /**
     * @return the seatNo
     */
    @Column(name="SEAT_NO", length=10)
    public String getSeatNo() {
        return seatNo;
    }



    /**
     * @param seatNo the seatNo to set
     */
    public void setSeatNo(String seatNo) {
        this.seatNo = seatNo;
    }


    /**
     * @return the payDue
     */
    @Column(name="PAY_DUE", nullable=false)
    public Date getPayDue() {
        return payDue;
    }


    /**
     * @param payDue the payDue to set
     */
    public void setPayDue(Date payDue) {
        this.payDue = payDue;
    }


    /**
     * @return the paymentItems
     */
    @OneToMany(cascade = CascadeType.ALL, mappedBy="payment")
    public List<PaymentItem> getPaymentItems() {
        return paymentItems;
    }


    /**
     * @param paymentItems the paymentItems to set
     */
    public void setPaymentItems(List<PaymentItem> paymentItems) {
        this.paymentItems = paymentItems;
    }




    /**
     * @return the paymentCanceled
     */
    @OneToOne
    @JoinColumn(name="PAYMENT_CANCELED_PK")
    public PaymentCanceled getPaymentCanceled() {
        return paymentCanceled;
    }



    /**
     * @param paymentCanceled the paymentCanceled to set
     */
    public void setPaymentCanceled(PaymentCanceled paymentCanceled) {
        this.paymentCanceled = paymentCanceled;
    }


    /**
     * @return the writeOffPayment
     */
    @OneToOne
    @JoinColumn(name="WRITE_OFF_PAYMENT_PK")
    public WriteOffPayment getWriteOffPayment() {
        return writeOffPayment;
    }


    /**
     * @param writeOffPayment the writeOffPayment to set
     */
    public void setWriteOffPayment(WriteOffPayment writeOffPayment) {
        this.writeOffPayment = writeOffPayment;
    }

    
    
    /**
     * @return the extraColumns
     */
    @OneToOne(cascade={CascadeType.ALL})
    @JoinColumn(name="EXTRA_COLUMNS_PK")
    public ExtraColumns getExtraColumns() {
        return extraColumns;
    }


    
    /**
     * @param extraColumns the extraColumns to set
     */
    public void setExtraColumns(ExtraColumns extraColumns) {
        this.extraColumns = extraColumns;
    }


    /**
     * @return the pdfFileName
     */
    @Column(name="PDF_FILE_NAME", nullable=false, length=100)
    public String getPdfFileName() {
        return pdfFileName;
    }

    
    /**
     * @param pdfFileName the pdfFileName to set
     */
    public void setPdfFileName(String pdfFileName) {
        this.pdfFileName = pdfFileName;
    }

    
    /**
     * @return the pdfFilePathOnServer
     */
    @Column(name="PDF_FILE_PATH_ON_SERVER", nullable=false, length=255)
    public String getPdfFilePathOnServer() {
        return pdfFilePathOnServer;
    }

    
    /**
     * @param pdfFilePathOnServer the pdfFilePathOnServer to set
     */
    public void setPdfFilePathOnServer(String pdfFilePathOnServer) {
        this.pdfFilePathOnServer = pdfFilePathOnServer;
    }


    
    /**
     * @return the paymentNote1
     */
    @Column(name="PAYMENT_NOTE_1", length=500)
    public String getPaymentNote1() {
        return paymentNote1;
    }


    
    /**
     * @param paymentNote1 the paymentNote1 to set
     */
    public void setPaymentNote1(String paymentNote1) {
        this.paymentNote1 = paymentNote1;
    }


    
    /**
     * @return the paymentNote2
     */
    @Column(name="PAYMENT_NOTE_2", length=500)
    public String getPaymentNote2() {
        return paymentNote2;
    }


    
    /**
     * @param paymentNote2 the paymentNote2 to set
     */
    public void setPaymentNote2(String paymentNote2) {
        this.paymentNote2 = paymentNote2;
    }


    
    /**
     * @return the paymentNote3
     */
    @Column(name="PAYMENT_NOTE_3", length=255)
    public String getPaymentNote3() {
        return paymentNote3;
    }


    
    /**
     * @param paymentNote3 the paymentNote3 to set
     */
    public void setPaymentNote3(String paymentNote3) {
        this.paymentNote3 = paymentNote3;
    }


    
    /**
     * @return the mainBank
     */
    @Column(name="MAIN_BANK", length=255)
    public String getMainBank() {
        return mainBank;
    }


    
    /**
     * @param mainBank the mainBank to set
     */
    public void setMainBank(String mainBank) {
        this.mainBank = mainBank;
    }
    
    
    /**
     * @return the real_pay_amount (2011/09/07 YD)
     */
    @Column(name="REAL_PAY_AMOUNT")
    public Long getRealPayAmount() {
        return realPayAmount;
    }


    /**
     * @param real_pay_amount the totalAmount to set (2011/09/07 YD)
     */
    public void setRealPayAmount(Long realPayAmount) {
        this.realPayAmount = realPayAmount;
    }
    
}
